<?php
namespace Service\Model;

use \Service\Library\LibConfig;
use \Service\Library\LibPdo;

/**
 * Base Model
 * All model must extends this model
 */
abstract class BaseModel
{
    /**
     * model instance
     * @param array
     */
    private static $ins = [];

    private $host;
    private $port;
    private $user;
    private $pwd;
    private $charset;
    private $db_name;

    private $Pdo;

    protected $table;

    /**
     * Get instance
     */
    public static function getIns()
    {
        $ins = null;

        $class = get_called_class();
        if(isset(self::$ins[$class])) {
            $ins = & self::$ins[$class];
        } else {
            self::$ins[$class] = $ins = new $class(LibConfig::get('mysql'));
        }

        return $ins; 
    }

    public function __construct($mysql_config)
    {
        if(!$mysql_config) {
            return;
        }

        foreach($mysql_config as $mck => $mcv) {
            $this->{$mck} = $mcv;
        }

        return $this->getPdo();
    }

    /**
     * @return LibPdo
     */
    protected function getPdo()
    {
        $class_name = get_class($this);
        
        if (!isset($this->Pdo) || !isset($this->Pdo[$class_name])) {
            $charset = isset($this->charset) ? $this->charset : 'utf8mb4';
            $this->Pdo[$class_name]['Pdo'] = LibPdo::initPdo(
                $this->host,
                $this->port,
                $this->user,
                $this->pwd,
                $this->charset,
                $this->db_name
            );
        }

        $this->Pdo[$class_name]['Pdo']->setPdoDT($this->table, $this->db_name);

        return $this->Pdo[$class_name]['Pdo'];
    }

    /**
     * 创建一条记录
     * @param array $params
     * @return mixed
     */
    public function create($params)
    {
        if (empty($params) || !is_array($params)) {
            return false;
        }

        $time = time();
        $params['created_at'] = $time;
        $params['updated_at'] = $time;

        return $this->getPDO()->insert($params);
    }

    /**
     * 根据主键ID 更新一条记录
     * @param $id int
     * @param $params array()
     */
    public function updateById($id, $params)
    {
        if (!$id || !is_array($params)) {
            return false;
        }
        
        $params['updated_at'] = time();

        return $this->getPDO()->updateById($id, $params);
    }

    /**
     * 根据主键ID 删除一条记录
     * @param $id int
     */
    public function deleteById($id)
    {
        if (!$id) {
            return false;
        }

        return $this->getPDO()->deleteById($id);
    }

    /**
     * 根据主键ID 查找一条记录
     * @param $id int
     */
    public function findById($id)
    {
        if (!$id) {
            return false;
        }

        return $this->getPDO()->findById($id);
    }

    /**
     * 获取记录数量
     * @param array $where
     * @return integer
     */
    public function count(array $where = [])
    {
        return $this->getPDO()->count($where);
    }

    /**
     * select
     * @param $sql
     * @param array $params
     * @return array|bool|int|mixed
     */
    public function queryWithPrepare($sql, array $params = [])
    {
        return $sql ? $this->getPdo()->query_with_prepare($sql, $params) : null;
    }

    /**
     * select
     * @param $sql
     * @param array $param
     * @return array|bool|int|mixed
     */
    public function queryOneWithPrepare($sql, array $param = [])
    {
        return $sql ? $this->getPdo()->query_one_with_prepare($sql, $param) : null;
    }

    /**
     * insert|update|delete
     * @param $sql
     * @param array $param
     * @return array|bool|int|mixed
     */
    public function execWithPrepare($sql, array $param = [])
    {
        return $sql ? $this->getPdo()->exec_with_prepare($sql, $param) : null;
    }

    /**
     * @param array $where
     * @param array $order
     * @param int $offset
     * @param int $limit
     * @param string $fields
     * @param string $fore_index
     * @return array|bool|int|mixed
     */
    public function getAll(array $where = [], array $order = [], $offset = 0, $limit = 0, $fields = '', $fore_index = '')
    {
        return $this->getPdo()->findAll($where, $order, $offset, $limit, $fields, $fore_index);
    }
}